1   // Copyright 2007, 2008, 2010, 2011 The Apache Software Foundation
2   //
3   // Licensed under the Apache License, Version 2.0 (the "License");
4   // you may not use this file except in compliance with the License.
5   // You may obtain a copy of the License at
6   //
7   //     http://www.apache.org/licenses/LICENSE-2.0
8   //
9   // Unless required by applicable law or agreed to in writing, software
10  // distributed under the License is distributed on an "AS IS" BASIS,
11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  // See the License for the specific language governing permissions and
13  // limitations under the License.
14  
15  package org.apache.tapestry5.internal.services;
16  
17  import org.apache.tapestry5.ComponentEventCallback;
18  import org.apache.tapestry5.TapestryMarkers;
19  import org.apache.tapestry5.ioc.Invokable;
20  import org.apache.tapestry5.ioc.OperationTracker;
21  import org.apache.tapestry5.runtime.Event;
22  import org.slf4j.Logger;
23  
24  @SuppressWarnings("all")
25  public class EventImpl implements Event
26  {
27      private boolean aborted;
28  
29      private String methodDescription;
30  
31      private final ComponentEventCallback handler;
32  
33      private final Logger logger;
34  
35      private final boolean debugEnabled;
36  
37      protected final OperationTracker tracker;
38  
39      /**
40       * @param handler informed of return values from methods, deems when the event is aborted
41       * @param logger  used to log method invocations
42       * @param tracker
43       */
44      public EventImpl(ComponentEventCallback handler, Logger logger, OperationTracker tracker)
45      {
46          this.tracker = tracker;
47          assert handler != null;
48          this.handler = handler;
49          this.logger = logger;
50  
51          // TAP5-471: Thousands of calls to isDebugEnabled() do add up
52          debugEnabled = logger.isDebugEnabled();
53      }
54  
55      public boolean isAborted()
56      {
57          return aborted;
58      }
59  
60      public void setMethodDescription(String methodDescription)
61      {
62          if (debugEnabled)
63              logger.debug(TapestryMarkers.EVENT_HANDLER_METHOD, "Invoking: " + methodDescription);
64  
65          this.methodDescription = methodDescription;
66      }
67  
68      @SuppressWarnings("unchecked")
69      public boolean storeResult(final Object result)
70      {
71          // Given that this method is *only* invoked from code
72          // that is generated at runtime and proven to be correct,
73          // this should never, ever happen. But what the hell,
74          // let's check anyway.
75  
76          if (aborted)
77          {
78              throw new IllegalStateException(String.format("Can not store result from invoking method %s, because an event result value has already been obtained from some other event handler method.", methodDescription));
79          }
80  
81  
82          if (result != null)
83          {
84              boolean handleResult =
85                      tracker.invoke("Handling result from method " + methodDescription + '.', new Invokable<Boolean>()
86                      {
87                          public Boolean invoke()
88                          {
89                              return handler.handleResult(result);
90                          }
91                      });
92  
93              aborted |= handleResult;
94          }
95  
96          return aborted;
97      }
98  
99      protected String getMethodDescription()
100     {
101         return methodDescription;
102     }
103 }